#include "WaveEndless.h"
#include "UnitModels.h"

#include <algorithm>

namespace VectorTD
{
	bool spawneTimeComp(const std::pair<unsigned int, Unit*>& p_p1, const std::pair<unsigned int, Unit*>& p_p2)
	{
		return p_p1.first < p_p2.first;
	}

	WaveEndless::WaveEndless(int p_difficultyLvl, Map* p_map)
		: Wave()
		, m_units()
		, m_unitsToBeSpawn()
		, m_elapsedTime(0)
		, m_map(p_map)
	{
		if(p_difficultyLvl < 10)
		{
			// --------------------------------------------------------------------------------
			// We generate the small unit of the wave
			unsigned int smallUnitHp = (10 + p_difficultyLvl * p_difficultyLvl) / 4;
			float smallUnitSpeed = 0.05f;
			int smallUnitNumber = p_difficultyLvl * 2 + 4;
			//int smallUnitNumber = 1;
			float smallUnitScale = 0.14f;
			float smallUnitRotationSpeed = smallUnitSpeed*1440.0f;

			// We choose a random model for small unit
			int numModel = sizeof(BasicModels) / sizeof(const char*);
			int randomIndex = static_cast<int>((numModel) * rand()/(RAND_MAX + 1.0));

			ASSERT(randomIndex >= 0 && randomIndex < numModel, "randomIndex is wrong : %d (max is : %d)", randomIndex, numModel);

			// We load the model
			GameRenderer::GameMesh* unitModel = LoadUnitModel(BasicModels[randomIndex]);

			for(int i = 0 ; i < smallUnitNumber ; i++)
			{
				m_units.push_back(std::make_pair(i*500 + 500, new Unit(unitModel, smallUnitSpeed, smallUnitHp, smallUnitRotationSpeed, smallUnitScale, m_map)));
			}
			// --------------------------------------------------------------------------------
			// TODO: Generate other types of units

			// --------------------------------------------------------------------------------
			// We sort the vector of pair<spawn time, unit> based on spawn time
			m_units.sort(spawneTimeComp);

			// --------------------------------------------------------------------------------
		}
	}

	WaveEndless::~WaveEndless()
	{
	}

	bool WaveEndless::Update(double p_deltaMs)
	{
		m_elapsedTime += p_deltaMs;

		for(std::list<std::pair<unsigned int, Unit*> >::iterator it = m_units.begin() ; it != m_units.end() ; )
		{
			if(it->first > m_elapsedTime)
				break;
			else
			{
				m_unitsToBeSpawn.push_back(it->second);
				it = m_units.erase(it);
			}
		}

		if(m_units.size() != 0 || m_unitsToBeSpawn.size() != 0)
			return true;
		else
			return false;
	}

	std::vector<Unit*>& WaveEndless::GetUpdatedCreeps()
	{
		return m_unitsToBeSpawn;
	}
}